﻿using OpenCvSharp.Dnn;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace Camera_002
{
    internal class Class1
    {
        const int width = 300;
        const int height = 300;
        const float meanVal = 127.5f;
        const float scaleFactor = 0.007843f;
        string[] classNames = new string[] { "background",
"aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair",
"cow", "diningtable", "dog", "horse",
"motorbike", "person", "pottedplant",
"sheep", "sofa", "train", "tvmonitor" };

        String modelFile = "d://code//MobileNetSSD_deploy.caffemodel";
        String model_text_file = "d://code//MobileNetSSD_deploy.prototxt";
        //string srcPath = @"d:\code\";


        public void Run(string imagefile)
        {
            //string imagefile = srcPath + "vehicle_test.jpg";

            //VideoCapture capture = new VideoCapture(0);
            //int w = capture.FrameWidth;
            //int h = capture.FrameHeight;

            //Cv2.NamedWindow("input", WindowFlags.AutoSize);

            // set up net
            Net net = Net.ReadNetFromCaffe(model_text_file, modelFile);
            Mat frame;
            //while (capture.Read(frame))
            frame = Cv2.ImRead(imagefile);
            {
                //Cv2.ImShow("input", frame);

                // 预测
                Mat inputblob = CvDnn.BlobFromImage(frame, scaleFactor, new Size(width, height), meanVal, false);

                net.SetInput(inputblob, "data");
                Mat detection = net.Forward("detection_out");


                //检测
                Mat detectionMat = new Mat(detection.Size(2), detection.Size(3), MatType.CV_32F, detection.Ptr(0));
                float confidence_threshold = 0.3f;

                bool found = false;
                int CAT_CLASS = 8;
                for (int i = 0; i < detectionMat.Rows; i++)
                {
                    float confidence = detectionMat.At<float>(i, 2);
                    if (confidence > confidence_threshold)
                    {
                        int objIndex = (int)(detectionMat.At<float>(i, 1));
                        if(objIndex == CAT_CLASS)
                        {
                            found = true;
                        }
                        float tl_x = detectionMat.At<float>(i, 3) * frame.Cols;
                        float tl_y = detectionMat.At<float>(i, 4) * frame.Rows;
                        float br_x = detectionMat.At<float>(i, 5) * frame.Cols;
                        float br_y = detectionMat.At<float>(i, 6) * frame.Rows;

                        Rect object_box = new Rect((int)tl_x, (int)tl_y, (int)(br_x - tl_x), (int)(br_y - tl_y));
                        Cv2.Rectangle(frame, object_box, new Scalar(0, 0, 255), 2, LineTypes.Link8, 0);
                        float txt_x = tl_x;
                        float txt_y = tl_y;
                        if(tl_x < 50)
                        {
                            txt_x = tl_x + 50;
                        }
                        if(tl_y < 50)
                        {
                            txt_y = tl_y + 50;
                        }
                        Cv2.PutText(frame, classNames[objIndex], new Point(txt_x, txt_y), HersheyFonts.HersheySimplex, 1.0, new Scalar(255, 0, 0), 2);
                    }
                }
                if(found)
                {
                    //MessageBox.Show("活捉一只猫");
                    Cv2.ImShow("识别效果-发现猫了", frame);
                }
                else
                {
                    Cv2.ImShow("识别效果", frame);
                }

                //int c = Cv2.WaitKey(5);
                //if (c == 27)
                //{ // ESC退出
                //    break;
                //}
                Cv2.WaitKey(0);
                Cv2.DestroyAllWindows();
            }
        }
        public void RunBit(System.Drawing.Bitmap bitmap)
        {
            //string imagefile = srcPath + "vehicle_test.jpg";

            //VideoCapture capture = new VideoCapture(0);
            //int w = capture.FrameWidth;
            //int h = capture.FrameHeight;

            //Cv2.NamedWindow("input", WindowFlags.AutoSize);

            // set up net
            Net net = Net.ReadNetFromCaffe(model_text_file, modelFile);
            Mat frame;
            //while (capture.Read(frame))
            frame = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
            {
                //Cv2.ImShow("input", frame);

                // 预测
                Mat inputblob = CvDnn.BlobFromImage(frame, scaleFactor, new OpenCvSharp.Size(width, height), meanVal, false);

                net.SetInput(inputblob, "data");
                Mat detection = net.Forward("detection_out");


                //检测
                Mat detectionMat = new Mat(detection.Size(2), detection.Size(3), MatType.CV_32F, detection.Ptr(0));
                float confidence_threshold = 0.3f;

                bool found = false;
                int CAT_CLASS = 8;
                for (int i = 0; i < detectionMat.Rows; i++)
                {
                    float confidence = detectionMat.At<float>(i, 2);
                    if (confidence > confidence_threshold)
                    {
                        int objIndex = (int)(detectionMat.At<float>(i, 1));
                        if (objIndex == CAT_CLASS)
                        {
                            found = true;
                        }
                        float tl_x = detectionMat.At<float>(i, 3) * frame.Cols;
                        float tl_y = detectionMat.At<float>(i, 4) * frame.Rows;
                        float br_x = detectionMat.At<float>(i, 5) * frame.Cols;
                        float br_y = detectionMat.At<float>(i, 6) * frame.Rows;

                        Rect object_box = new Rect((int)tl_x, (int)tl_y, (int)(br_x - tl_x), (int)(br_y - tl_y));
                        Cv2.Rectangle(frame, object_box, new Scalar(0, 0, 255), 2, LineTypes.Link8, 0);
                        float txt_x = tl_x;
                        float txt_y = tl_y;
                        if (tl_x < 50)
                        {
                            txt_x = tl_x + 50;
                        }
                        if (tl_y < 50)
                        {
                            txt_y = tl_y + 50;
                        }
                        Cv2.PutText(frame, classNames[objIndex], new OpenCvSharp.Point(txt_x, txt_y), HersheyFonts.HersheySimplex, 1.0, new Scalar(255, 0, 0), 2);
                    }
                }
                if (found)
                {
                    //MessageBox.Show("活捉一只猫");
                    Cv2.ImShow("识别效果-发现猫了", frame);
                }
                else
                {
                    Cv2.ImShow("识别效果", frame);
                }

                //int c = Cv2.WaitKey(5);
                //if (c == 27)
                //{ // ESC退出
                //    break;
                //}
                Cv2.WaitKey(0);
                Cv2.DestroyAllWindows();
            }
        }
        public bool RunSlient(System.Drawing.Bitmap bitmap)
        {
            //string imagefile = srcPath + "vehicle_test.jpg";

            //VideoCapture capture = new VideoCapture(0);
            //int w = capture.FrameWidth;
            //int h = capture.FrameHeight;

            //Cv2.NamedWindow("input", WindowFlags.AutoSize);

            // set up net
            Net net = Net.ReadNetFromCaffe(model_text_file, modelFile);
            Mat frame;
            //while (capture.Read(frame))
            frame = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
            {
                //Cv2.ImShow("input", frame);

                // 预测
                Mat inputblob = CvDnn.BlobFromImage(frame, scaleFactor, new OpenCvSharp.Size(width, height), meanVal, false);

                net.SetInput(inputblob, "data");
                Mat detection = net.Forward("detection_out");


                //检测
                Mat detectionMat = new Mat(detection.Size(2), detection.Size(3), MatType.CV_32F, detection.Ptr(0));
                float confidence_threshold = 0.3f;

                bool found = false;
                int CAT_CLASS = 8;
                for (int i = 0; i < detectionMat.Rows; i++)
                {
                    float confidence = detectionMat.At<float>(i, 2);
                    if (confidence > confidence_threshold)
                    {
                        int objIndex = (int)(detectionMat.At<float>(i, 1));
                        if (objIndex == CAT_CLASS)
                        {
                            found = true;
                            return found;
                        }
                    }
                }
                return false;
            }
        }
    }

}


